﻿using UnityEngine;
using UnityEngine.UI;
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using FrostweepGames.UniversalMicrophoneLibrary;

public class VoiceDialogWebGL : MonoBehaviour
{
    [SerializeField] private AudioNetworkHandler networkHandler;
    [SerializeField] private Text hintText;        // 提示文本
    [SerializeField] private Text debugText;       // 调试文本
    [SerializeField] private GameObject hintBackground;  // 提示背景

    private AudioClip recordedClip;
    private bool isRecording = false;
    private float hintStopTime = 0;
    private string recognitionResult = "";
    private string recognitionResultType = "";
    private Dictionary<int, string> audioChunks = new Dictionary<int, string>();

    private const int SAMPLE_RATE = 44100;  // 采样率
    private const int RECORD_LENGTH = 10;    // 录音长度（秒）
    private const int BIT_DEPTH = 16;       // 位深度

#if UNITY_WEBGL && !UNITY_EDITOR
    [DllImport("__Internal")]
    private static extern void StartRecording();
    
    [DllImport("__Internal")]
    private static extern void StopRecording();
#endif
    void SomeMethod()
    {
        AudioClip recordedClip = GetRecordedClip(); // 假设这是获取录制音频的方法
        byte[] audioData = ConvertAudioClipToByteArray(recordedClip);
        if (audioData != null)
        {
            StartCoroutine(networkHandler.SendAudioBytes(audioData));
        }
    }
    private void Start()
    {
        networkHandler = GetComponent<AudioNetworkHandler>();
        if (networkHandler == null)
        {
            Debug.LogError("AudioNetworkHandler 组件未找到！");
            return;
        }
        // 检查并初始化所有必需组件
        if (networkHandler == null)
            networkHandler = GetComponent<AudioNetworkHandler>();

        if (hintText == null)
            Debug.LogError("未找到 hintText 组件");

        if (debugText == null)
            Debug.LogError("未找到 debugText 组件");

        if (hintBackground == null)
            Debug.LogError("未找到 hintBackground 组件");

        // 初始显示一些文本确认 UI 正常工作
        if (debugText != null)
            debugText.text = "系统已就绪...";

        if (hintText != null)
            hintText.text = "点击按钮开始录音";

        networkHandler.OnRequestSuccess += HandleResponse;
        networkHandler.OnRequestError += HandleError;
    }

    private void Update()
    {
        // 自动隐藏提示
        if (hintBackground != null && hintBackground.activeSelf && Time.time > hintStopTime)
        {
            hintBackground.SetActive(false);
            hintText.text = "";
        }
    }

    private void HandleResponse(SpeechResponse response)
    {
        if (response == null || response.data == null)
        {
            ShowHint("识别错误，请再试一次。", 3f);
            return;
        }

        Debug.Log($"响应内容: {JsonUtility.ToJson(response)}");

        if (response.data.err_msg == "success.")
        {
            recognitionResultType = "[ok]";
            recognitionResult = response.data.result[0];  // 获取第一个识别结果

            // 更新UI显示识别结果，而不是状态
            if (debugText != null)
            {
                debugText.text = recognitionResult;  // 直接显示识别到的文本
            }

            hintBackground.SetActive(false);
            hintText.text = "";
        }
        else if (response.data.err_no != 0)
        {
            recognitionResultType = "[error]";
            ShowHint("识别错误，请再试一次。", 3f);

            if (debugText != null)
            {
                debugText.text = "识别失败";
            }
        }
    }

    private void HandleError(string error)
    {
        Debug.LogError($"发生错误: {error}");
        ShowHint("识别错误，请再试一次。", 3f);
    }

    private void ShowHint(string message, float duration)
    {
        if (hintBackground != null && hintText != null)
        {
            hintBackground.SetActive(true);
            hintText.text = message;
            hintStopTime = Time.time + duration;
        }
    }

    private void UpdateDebugText(string message)
    {
        if (debugText != null)
        {
            debugText.text = message;
            Debug.Log(message); // 同时输出到控制台
        }
    }

    // 开始录音
    public void OnStartRecording()
    {
        if (isRecording) return;

#if !UNITY_WEBGL || UNITY_EDITOR
        isRecording = true;
        
        // 检查并选择最佳麦克风设备
        string[] devices = Microphone.devices;
        string bestDevice = null;
        if (devices.Length > 0)
        {
            bestDevice = devices[0];  // 使用第一个可用设备
            UpdateDebugText($"使用麦克风设备: {bestDevice}");
        }
        else
        {
            UpdateDebugText("未找到麦克风设备！");
            return;
        }
        
        recordedClip = UnityEngine.Microphone.Start(bestDevice, false, RECORD_LENGTH, SAMPLE_RATE);
        UpdateDebugText("Unity录音开始...");
#else
            StartRecording();
            isRecording = true;
            UpdateDebugText("WebGL录音开始...");
#endif
    }

    // 结束录音
    public void OnStopRecording()
    {
        if (!isRecording) return;

#if !UNITY_WEBGL || UNITY_EDITOR
        UnityEngine.Microphone.End(null);
        isRecording = false;
        UpdateDebugText("Unity录音结束，准备发送...");

        if (recordedClip != null)
        {
            this.GetComponent<AudioSource>().clip = recordedClip;
            byte[] audioData = ConvertAudioClipToByteArray(recordedClip);
            StartCoroutine(networkHandler.SendAudioBytes(audioData));
        }
#else
            StopRecording();
            isRecording = false;
            UpdateDebugText("WebGL录音结束，等待数据...");
#endif
    }

    // 接收音频数据的回调方法
    public void OnAudioDataReceived(byte[] audioData)
    {
        Debug.Log("收到音频数据，长度: " + audioData.Length);
        StartCoroutine(networkHandler.SendAudioBytes(audioData));
    }

    private void OnDestroy()
    {
#if !UNITY_WEBGL || UNITY_EDITOR
        if (isRecording)
        {
            UnityEngine.Microphone.End(null);
        }
#endif

        if (networkHandler != null)
        {
            networkHandler.OnRequestSuccess -= HandleResponse;
            networkHandler.OnRequestError -= HandleError;
        }
    }

    [System.Serializable]
    private class AudioChunkData
    {
        public int index;
        public int total;
        public string data;
    }

    // 这个方法会被 jslib 调用
    public void ReceiveAudioChunk(string jsonData)
    {
        try
        {
            var chunkData = JsonUtility.FromJson<AudioChunkData>(jsonData);

            // 存储接收到的块
            audioChunks[chunkData.index] = chunkData.data;

            // 检查是否收到所有块
            if (audioChunks.Count == chunkData.total)
            {
                // 合并所有块
                string completeBase64 = "";
                for (int i = 0; i < chunkData.total; i++)
                {
                    if (audioChunks.TryGetValue(i, out string chunk))
                    {
                        completeBase64 += chunk;
                    }
                }

                // 转换回字节数组
                byte[] audioData = Convert.FromBase64String(completeBase64);

                // 处理完整的音频数据
                ProcessAudioData(audioData);

                // 清理
                audioChunks.Clear();
            }
        }
        catch (Exception e)
        {
            Debug.LogError($"处理音频数据块时出错: {e.Message}");
        }
    }

    private void ProcessAudioData(byte[] audioData)
    {
        UpdateDebugText($"正在理音频数据: {audioData.Length} 字节");
        ShowHint("正在处理音频...", 2f);
        StartCoroutine(networkHandler.SendAudioBytes(audioData));
    }

    private AudioClip GetRecordedClip()
    {
        // 这里是获录制音频的逻辑
        return null; // 示例返回空
    }

    private byte[] ConvertAudioClipToByteArray(AudioClip clip)
    {
        if (clip == null)
        {
            Debug.LogError("AudioClip 为空！");
            return null;
        }

        // 获取音频数据
        float[] samples = new float[clip.samples * clip.channels];
        clip.GetData(samples, 0);

        // 计算WAV文件的大小
        int headerSize = 44; // WAV文件头的大小
        int dataSize = samples.Length * 2; // 16位采样，每个样本2字节
        int fileSize = headerSize + dataSize;

        byte[] wavFile = new byte[fileSize];

        // 写入WAV文件头
        // RIFF头
        System.Text.Encoding.ASCII.GetBytes("RIFF").CopyTo(wavFile, 0);
        BitConverter.GetBytes(fileSize - 8).CopyTo(wavFile, 4); // 文件大小 - 8
        System.Text.Encoding.ASCII.GetBytes("WAVE").CopyTo(wavFile, 8);

        // fmt块
        System.Text.Encoding.ASCII.GetBytes("fmt ").CopyTo(wavFile, 12);
        BitConverter.GetBytes(16).CopyTo(wavFile, 16); // fmt块大小
        BitConverter.GetBytes((short)1).CopyTo(wavFile, 20); // PCM格式
        BitConverter.GetBytes((short)clip.channels).CopyTo(wavFile, 22); // 通道数
        BitConverter.GetBytes(clip.frequency).CopyTo(wavFile, 24); // 采样率
        BitConverter.GetBytes(clip.frequency * clip.channels * 2).CopyTo(wavFile, 28); // 字节率
        BitConverter.GetBytes((short)(clip.channels * 2)).CopyTo(wavFile, 32); // 块对齐
        BitConverter.GetBytes((short)16).CopyTo(wavFile, 34); // 位深度

        // data块
        System.Text.Encoding.ASCII.GetBytes("data").CopyTo(wavFile, 36);
        BitConverter.GetBytes(dataSize).CopyTo(wavFile, 40);

        // 写入音频数据
        int dataIndex = 44;
        foreach (float sample in samples)
        {
            // 将float转换为16位整数
            short shortSample = (short)(Mathf.Clamp(sample, -1f, 1f) * 32767f);
            byte[] sampleBytes = BitConverter.GetBytes(shortSample);
            sampleBytes.CopyTo(wavFile, dataIndex);
            dataIndex += 2;
        }

        return wavFile;
    }
}


